﻿
using AB.ServiceDirectory.Commons.DataFilters;

namespace AB.ServiceDirectory.Dao
{
    using System;
    using System.Data.SqlClient;
    using System.Linq;
    using Commons;
    using Entities;

    /// <summary>
    /// HSupportingMaterialDao Class
    /// </summary>
    [Serializable]
    public class HSupportingMaterialDao
    {
        [NonSerialized] private readonly ServicesDirectoryDataContext _context = DB.Context;

        /// <summary>
        /// Gets the list.
        /// </summary>
        /// <param name="filter">The filter.</param>
        /// <param name="sortType">Type of the sort.</param>
        /// <param name="startRowIndex">Start index of the row.</param>
        /// <param name="max">The max.</param>
        /// <returns></returns>
        public IQueryable<SupportingMaterial> GetList(HSupportingMaterialFilter filter, string sortType,
                                                      int startRowIndex, int max)
        {
            IQueryable<SupportingMaterial> data = from sm in _context.SupportingMaterials
                                                  select sm;

            //filter
            if (filter != null)
            {
                data = GetListQuery(data, filter);
            }

            //sort
            data = GetListSort(data, sortType);

            //Limit the results
            data = data.Skip(startRowIndex).Take(max);

            //return Data
            return data;
        }

        /// <summary>
        /// Gets the list sort.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <param name="sortType">Type of the sort.</param>
        /// <returns></returns>
        private static IQueryable<SupportingMaterial> GetListSort(IQueryable<SupportingMaterial> data, string sortType)
        {
            bool sortDescending = false;
            if (!string.IsNullOrEmpty(sortType))
            {
                string[] values = sortType.Split(' ');
                sortType = values[0];
                if (values.Length > 1)
                {
                    sortDescending = (values[1] == "DESC");
                }

                switch (sortType)
                {
                    case "URL":
                        data = sortDescending ? data.OrderByDescending(sm => sm.Url) : data.OrderBy(sm => sm.Url);
                        break;
                    case "Description":
                        data = sortDescending
                                   ? data.OrderByDescending(sm => sm.Description)
                                   : data.OrderBy(sm => sm.Description);
                        break;
                    case "AddedBy":
                        data = sortDescending
                                   ? data.OrderByDescending(sm => sm.User.Account)
                                   : data.OrderBy(sm => sm.User.Account);
                        break;
                    case "Type":
                        data = sortDescending ? data.OrderByDescending(sm => sm.Type) : data.OrderBy(sm => sm.Type);
                        break;
                    case "AddedDate":
                        data = sortDescending
                                   ? data.OrderByDescending(sm => sm.AddedDate)
                                   : data.OrderBy(sm => sm.AddedDate);
                        break;
                    case "IsActive":
                        data = sortDescending
                                   ? data.OrderByDescending(sm => sm.IsActive)
                                   : data.OrderBy(sm => sm.IsActive);
                        break;
                }
            }
            return data;
        }

        /// <summary>
        /// Gets the list query.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <param name="filter">The filter.</param>
        /// <returns></returns>
        private static IQueryable<SupportingMaterial> GetListQuery(IQueryable<SupportingMaterial> data,
                                                                   HSupportingMaterialFilter filter)
        {
            // Filter by Organization Id
            data = data.Where(sm => sm.OrganizationId == filter.OrganizationId);

            //Filter by include inactive
            if (!filter.IncludeInactive)
            {
                data = data.Where(sm => sm.IsActive == !filter.IncludeInactive);
            }
            return data;
        }

        /// <summary>
        /// Gets the list count.
        /// </summary>
        /// <param name="filter">The filter.</param>
        /// <returns></returns>
        public int GetListCount(HSupportingMaterialFilter filter)
        {
            IQueryable<SupportingMaterial> data = from sm in _context.SupportingMaterials
                                                  select sm;
            if (filter != null)
            {
                data = GetListQuery(data, filter);
            }
            return data.Count();
        }

        /// <summary>
        /// Gets the supporting material by id.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns></returns>
        public SupportingMaterial GetSupportingMaterialById(int id)
        {
            SupportingMaterial supportingMaterial =
                _context.SupportingMaterials.FirstOrDefault(sm => sm.SupportingMaterialId == id);
            return supportingMaterial;
        }

        /// <summary>
        /// Gets the type of all supporting material.
        /// </summary>
        /// <returns></returns>
        public IQueryable SelectAllSupportingMaterialTypes()
        {
            var data = (from t in _context.SupportingMaterials
                        select new {TypeId = t.Type, TypeName = t.Type}).Distinct();
            return data;
        }

        /// <summary>
        /// Inserts the supporting material.
        /// </summary>
        /// <param name="supportingMaterial">The supporting material.</param>
        /// <returns></returns>
        public bool InsertSupportingMaterial(SupportingMaterial supportingMaterial)
        {
            try
            {
                _context.SupportingMaterials.InsertOnSubmit(supportingMaterial);
                _context.SubmitChanges();
                return true;
            }
            catch (SqlException exception)
            {
                Log.GetLog(this).Error(exception);
                return false;
            }
        }

        /// <summary>
        /// Updates the supporting material.
        /// </summary>
        /// <param name="supportingMaterial">The supporting material.</param>
        /// <returns></returns>
        public bool UpdateSupportingMaterial(SupportingMaterial supportingMaterial)
        {
            try
            {
                //get supporting material for editing
                SupportingMaterial supportingMaterial1 =
                    _context.SupportingMaterials.FirstOrDefault(
                        sm => sm.SupportingMaterialId == supportingMaterial.SupportingMaterialId);

                if (supportingMaterial1 != null)
                {
                    supportingMaterial1.Url = supportingMaterial.Url;
                    supportingMaterial1.Description = supportingMaterial.Description;
                    supportingMaterial1.Type = supportingMaterial.Type;
                    supportingMaterial1.IsActive = supportingMaterial.IsActive;
                    _context.SubmitChanges();
                    return true;
                }
            }
            catch (SqlException e)
            {
                Log.GetLog(this).Error(e);
                return false;
            }
            return false;
        }

        /// <summary>
        /// Sets the supporting material.
        /// </summary>
        /// <param name="supportingMaterialId">The supporting material id.</param>
        /// <param name="status">if set to <c>true</c> [status].</param>
        public void SetSupportingMaterial(int supportingMaterialId, bool status)
        {
            SupportingMaterial supportingMaterial =
                _context.SupportingMaterials.FirstOrDefault(s => s.SupportingMaterialId == supportingMaterialId);
            if (supportingMaterial != null)
            {
                supportingMaterial.IsActive = status;
                _context.SubmitChanges();
            }
        }
    }
}